Skip to content

feat: attendance marking + spam prevention - #701

Open
palxsh01 wants to merge 1 commit into
Dev-Card:mainfrom
palxsh01:feat/attendance-marking
Open

feat: attendance marking + spam prevention#701
palxsh01 wants to merge 1 commit into
Dev-Card:mainfrom
palxsh01:feat/attendance-marking

Conversation

@palxsh01

Copy link
Copy Markdown

Summary

Lets a signed-in user mark themselves as attending an event (hackathon) as a Participant / Organizer / Mentor and leave again, with two independent guardrails against "attendance spam" (marking every hackathon without actually attending): a hard rate limit and a soft heuristic flag. Adds the web UI, the role field, the anti-spam logic, tests, and docs.

Closes #693


Type of Change

  • Bug fix
  • New feature
  • Refactor (no functional change)
  • UI / Design change
  • Tests only
  • Documentation
  • Infrastructure / DevOps
  • Security

What Changed

Backend (apps/backend)

  • prisma/schema.prisma — new AttendeeRole enum (PARTICIPANT | ORGANIZER | MENTOR) and role / flagged columns on EventAttendee; joinedAt now defaults to now(); added @@index([userId, joinedAt]) to back the spam-count query. Migration 20260722181416_attendee_role_and_spam_flag included.
  • src/validations/event.validation.tsjoinEventSchema accepts an optional role (defaults to PARTICIPANT).
  • src/routes/event.tsPOST /:slug/join validates/persists role and returns { message, role, flagged }; two anti-spam layers: a route-level rate limit (10 req/min → 429) and a heuristic soft-flag (≥8 joins in a 5-min window ⇒ flagged = true + audit log, join still succeeds). GET /:slug/attendees now exposes each attendee's public role; flagged is never exposed.

Web (apps/web)

  • src/pages/EventPage.tsx + .css — new /events/:slug page: event details, attendee count, role picker, mark/leave attendance, and a public attendee list with role badges. Handles 401 / 409 / 429 gracefully.
  • src/lib/api.tsapiFetch extended to support authenticated non-GET requests (Bearer token from localStorage['devcard-token']), a typed ApiError, and 204 handling.
  • src/App.tsx — registered the /events/:slug route.
  • src/shared/types.ts + index.ts — added EventDetail, EventAttendee, AttendeeRole.

Docs

  • Root README.md — new "Events & Attendance" section: endpoints, join example, error cases, and the Attendance spam rules (what triggers a flag vs. a block).
  • apps/web/README.md — "Pages" table (incl. /events/:slug) and an "Authentication for attendance" note on the devcard-token flow.

How to Test

  1. Apply the migration and start the stack: npm run db:migrate, then npm run dev:backend and npm run dev:web.
  2. Create an event, obtain a JWT from the backend auth route, and set it in the browser: localStorage.setItem('devcard-token', '<your-jwt>').
  3. Visit /events/<slug>: pick a role, click Mark attendance → count increments and a role badge appears. Click Leave event → count decrements. Re-marking returns "already attending" (409 path).
  4. Spam check: mark attendance on 8+ events within 5 minutes → the new records are stored flagged = true (join still succeeds); exceeding 10 joins/min returns 429.
  5. Automated: npm --prefix apps/backend run test (backend event.test.ts, 40 passed) and the apps/web Vitest suite (test/EventPage.test.tsx, 4 passed).

Checklist

  • My code follows the project's coding style (npm run lint passes).
  • TypeScript compiles without errors (npm run typecheck --workspaces --if-present).
  • I have added or updated tests for the changes I made.
  • All tests pass locally (npm run test --workspaces --if-present).
  • I have updated documentation where necessary.
  • No new console.log or debug statements left in the code.
  • Breaking changes are documented in this PR description.

Additional Context

  • Auth is intentionally minimal: the web app has no login flow yet, so authenticated actions read a JWT set manually in localStorage. Documented in apps/web/README.md; a full login flow is out of scope here.
  • Attending state on load: the page can't yet tell whether the current user is already attending (starts on "Mark attendance"); a duplicate join is handled gracefully via the 409 path.
  • Migration: 20260722181416_attendee_role_and_spam_flag/migration.sql was hand-authored (no DB was reachable in the dev environment). A reviewer should run prisma migrate dev against a real Postgres to confirm the checksum and history.
  • Anti-spam thresholds are tunable constants (SPAM_WINDOW_MINUTES, SPAM_MAX_JOINS) in apps/backend/src/routes/event.ts.

@vercel

vercel Bot commented Jul 22, 2026

Copy link
Copy Markdown

@palxsh01 is attempting to deploy a commit to the Prashantkumar Khatri's projects Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions github-actions Bot added backend gssoc:approved Required label for every approved PR. Gives the base +50 points and enables contribution tracking. web labels Jul 22, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Hi @palxsh01,

Thanks for opening this pull request.

This PR has been automatically classified based on the files modified.

Applied Labels

  • gssoc:approved
  • backend
  • web

Primary Review Area

  • backend

Reviewer

@Harxhit has been identified as the primary reviewer for this pull request.

If you have any questions regarding the affected area or implementation details, feel free to reach out to the assigned reviewer.

Thank you for your contribution!

@github-actions

Copy link
Copy Markdown
Contributor

CI — All Checks Passed

Backend — PASS

Check Result
Lint PASS
Test PASS
Typecheck PASS

Mobile — SKIP

Check Result
Lint -
Test -

Web — PASS

Check Result
Build PASS

Last updated: Wed, 22 Jul 2026 18:57:54 GMT

@palxsh01

Copy link
Copy Markdown
Author

Hi @Harxhit,
Please take a moment to review the PR and close it. A delayed review could lead to new merge conflicts arising.
Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend gssoc:approved Required label for every approved PR. Gives the base +50 points and enables contribution tracking. web

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Attendance marking + spam prevention

1 participant